﻿using System;

namespace Bettzueche.Dampfross
{
    /// <summary>
    /// Zeile-Spalte Struktur für Hex-Koordinaten mit +,-,* Operator.
    /// </summary>
    [Serializable]
    public struct HexKoordinate
    {
        /// <summary>"Zeilen"-Koordinate</summary>
        public int Row;

        /// <summary>"Spalten"-Koordinate</summary>
        public int Col;

        /// <summary>
        /// Initializes a new instance of the <see cref="HexKoordinate"/> struct.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <param name="col">The column.</param>
        public HexKoordinate(int row, int col) {
            Row = row;
            Col = col;
        }

        /// <summary>
        /// Returns a <see cref="System.String" /> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String" /> that represents this instance.
        /// </returns>
        public override string ToString() {
            return string.Format("Hex({0}, {1})", Row, Col);
        }

        /// <summary>
        /// Determines whether the specified <see cref="System.Object" />, is equal to this instance.
        /// </summary>
        /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public override bool Equals(object obj) {
            if (obj is HexKoordinate) {
                var other = (HexKoordinate)obj;
                return (this.Col == other.Col) && (this.Row == other.Row);
            }
            return false;
        }

        /// <summary>
        /// Determines whether the specified <see cref="Bettzueche.Dampfross.HexKoordinate">HexKoordinate</see>, is equal to this instance.
        /// </summary>
        /// <param name="coord">The <c>HexKoordinate</c> to compare with this instance.</param>
        /// <returns>
        ///   <c>true</c> if the specified <c>HexKoordinate</c> is equal to this instance; otherwise, <c>false</c>.
        /// </returns>
        public bool Equals(HexKoordinate coord) {
            return (this.Col == coord.Col) && (this.Row == coord.Row);
        }

        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>
        /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. 
        /// </returns>
        public override int GetHashCode() {
            return (13 * Row) ^ (31 * Col);
        }


        /// <summary>
        /// Implements the operator +.
        /// </summary>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>
        /// Addierte Zeilen und Spalten (Row+Row, Col+Col).
        /// </returns>
        public static HexKoordinate operator +(HexKoordinate a, HexKoordinate b) {
            return new HexKoordinate(a.Row + b.Row, a.Col + b.Col);
        }
        /// <summary>
        /// Implements the operator -.
        /// </summary>
        /// <param name="a">A</param>
        /// <param name="b">B</param>
        /// <returns>
        /// Subtrahierte Zeilen und Spalten (a.Row - b.Row, a.Col - b.Col).
        /// </returns>
        public static HexKoordinate operator -(HexKoordinate a, HexKoordinate b) {
            return new HexKoordinate(a.Row - b.Row, a.Col - b.Col);
        }
        /// <summary>
        /// Implements the operator *.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="scalar">The scalar.</param>
        /// <returns>
        /// Skalarmultiplikation von jeweils Zeile und Spalte.
        /// </returns>
        public static HexKoordinate operator *(HexKoordinate a, int scalar) {
            return new HexKoordinate(a.Row * scalar, a.Col * scalar);
        }
        /// <summary>
        /// Implements the operator *.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="scalar">The scalar.</param>
        /// <returns>
        /// Skalarmultiplikation von jeweils Zeile und Spalte.
        /// </returns>
        public static HexKoordinate operator *(int scalar, HexKoordinate a) {
            return new HexKoordinate(a.Row * scalar, a.Col * scalar);
        }
        /// <summary>
        /// Implements the operator ==.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="b">The b.</param>
        /// <returns>
        /// The result of the operator.
        /// </returns>
        public static bool operator ==(HexKoordinate a, HexKoordinate b) {
            return (a.Row == b.Row) && (a.Col == b.Col);
        }
        /// <summary>
        /// Implements the operator !=.
        /// </summary>
        /// <param name="a">A.</param>
        /// <param name="b">The b.</param>
        /// <returns>
        /// The result of the operator.
        /// </returns>
        public static bool operator !=(HexKoordinate a, HexKoordinate b) {
            return !((a.Row == b.Row) && (a.Col == b.Col));
        }
    }
}
